メインコンテンツへスキップ

All Posts

News bits

Chrome 135 リリース

Chrome 135 がリリース。非常に多くの機能追加や変更が行われている。以降ではいくつかピックアップして紹介する。

出展:https://developer.chrome.com/release-notes/135?hl=ja

#CSS カルーセルのサポート

CSS のみでカルーセルを実装するための機能が非常に多く実装された。現在は Chrome 135 以降でのみのサポート。

関連:CSS カルーセルを試す

#Invoker Commands API

HTML による宣言的な記述により指定された要素に指定されたコマンドを実行できる機能。現在は Chrome 135 以降および Edge 135 以降でのサポートのみ。

ポップオーバーやダイアログの開閉を行う組み込みコマンドが用意されており、JavaScript を用いずにポップオーバーやダイアログ要素とボタン要素の紐づけが行える。

html
<button commandfor="mydialog" command="show-modal">Show modal dialog</button>
<dialog id="mydialog">
  <button commandfor="mydialog" command="close">Close</button>
  Dialog Content
</dialog>

また、JavaScript を利用する必要があるが、独自のコマンドを渡して処理することも可能。その場合、次のようにcommandイベントでコマンドを受け取り処理を行う。

js
element.addEventListener("command", (event) => {
  if (event.command == "--rotate-left") {
    element.style.rotate = "-90deg";
  } else if (event.command == "--rotate-right") {
    element.style.rotate = "90deg";
  }
});

参考:https://developer.mozilla.org/en-US/docs/Web/API/Invoker_Commands_API

#Observable API

Observable API は、非同期イベントストリームを処理するための APi。現在は Chrome 135 以降でのサポートのみ。

命令型のaddEventListenerなどの記述に対して、宣言的な記述によるイベントハンドリングを可能。

要素がクリックされたログを出力する例:

js
element.when("click").subscribe({
  next: () => {
    console.log("clicked");
  },
});

追加で他の操作が完了するのを待つ例:

js
element
  .when("mousemove")
  .takeUntil(document.when("mouseup"))
  .subscribe({
    next: (e) => {
      console.log("mousemoved", e);
    },
  });

イベントから数値を計算する例:

js
const maxY = await element
  .when("mousemove")
  .takeUntil(element.when("mouseup"))
  .map((e) => e.clientY)
  .reduce((soFar, y) => Math.max(soFar, y), 0);

whenメソッドはObservableオブジェクトを返し、これに対してsubscribeメソッドを呼び出すことでイベントを購読する、takeUntilメソッドを呼び出すことで他の操作が完了するのを待つ、filterreduceなどで処理を行うといったことが出来る。

参考:

#setInterval の 1ms 以上へのクランプ削除

Chrome 135 以降では、1ms 未満のsetIntervalの呼び出しが 1ms に強制されない。

例えば、setInterval(() => {}, 0)は今まで 1ms の遅延が発生していたが、今後は 0ms の遅延で実行される。

#clip-path での shape 関数のサポート

clip-pathshape関数を利用することが可能になった。従来の方法に比べて、より柔軟な記述が可能。

css
.example {
  width: 100px;
  height: 100px;
  background-color: coral;
  clip-path: shape(from 0% 0%, line to 100% 0%, line to 50% 100%, close);
}

参考:https://developer.mozilla.org/en-US/docs/Web/CSS/basic-shape/shape

Chrome 125

Chrome 125 がリリースされました。

New in Chrome 125 | Blog | Chrome for Developers

#CSS Anchor Positioning

CSS Anchor Positioning は、CSS のみで指定された要素を基準に要素を配置する機能です。Chrome や Edge でしか現状利用できません。

Introducing the CSS anchor positioning API | Blog | Chrome for Developers

これは複数の新しいプロパティや値を含んでおり、色々なことが出来ます。以下に主なパターンを書き出しました。詳しくは記事を見てください。

css
.anchor {
  anchor-name: --anchor-el;
}
/* インセット領域を利用した配置 */
.anchored-notice-1 {
  position: absolute;
  /*  Anchor reference  */
  position-anchor: --anchor-el;
  /*  Position bottom of anchored elem at top center of anchor  */
  /* top, left, right, bottom, inline-(start|end), block-(start|end) */
  inset-area: top;
}
/* 絶対配置を利用した配置 */
.anchord-notice-2 {
  position: absolute;
  /*  Anchor reference  */
  position-anchor: --anchor-el;
  /*  Position bottom of positioned elem at top of anchor  */
  bottom: anchor(top);
  right: anchor(right);
  /*  Center justification to the anchor */
  justify-self: anchor-center;
}
.anchord-notice-3 {
  position: absolute;
  position-anchor: --anchor-el;
  inset-area: right span-bottom;
  /*
  * 配置位置をアンカーの位置に応じて変更する。
  */
  position-try-options: --bottom;
}
/* alternate position */
@position-try --bottom {
  inset-area: bottom;
}
.anchord-notice-4 {
  position: absolute;
  position-anchor: --anchor-el;
  inset-area: top;
  /* 自動的に反転させる flip-blockとflip-inlineの組み合わせ*/
  position-try-options: flip-block;
}
.anchord-notice-5 {
  position: fixed;
  position-anchor: --anchor-el;
  /* アンカーが表示されている間、配置された要素を表示し続ける */
  position-visibility: anchors-visible;
  bottom: anchor(top);
}

DEMO:

Anchor position tool

#Compute Pressure API

Compute Pressure API がサポートされました。現状 Chrome ぐらいでしか利用できません。

Compute Pressure API | Web Platform | Chrome for Developers

Compute Pressure API は、大きな負荷の変化を検出できます。これによりビデオ会議 Web アプリなどのリアルタイム アプリケーションで、負荷が高まった際に画質を落とすなどの対応ができます。

jsx
function callback(records) {
  const lastRecord = records[records.length - 1];
  console.log(`Current pressure ${lastRecord.state}`);
  if (lastRecord.state === "critical") {
    // disable video feeds
  } else if (lastRecord.state === "serious") {
    // disable video filter effects
  } else {
    // enable all video feeds and filter effects
  }
}

const observer = new PressureObserver(callback);
await observer.observe("cpu", {
  sampleInterval: 1000, // 1000ms
});

Storage Access API はクロスサイト Cookie の代替として導入された API です。iframe などを通して別のサイトに埋め込まれたコンテンツに対してサードパーティー Cookie へのアクセスを提供していました。Chrome 125 から indexedDB や localStorage など Cookie 以外のストレージにもアクセスできるようになりました。

Storage Access API - Web API | MDN

Storage Access API の使用 - Web API | MDN

#CSS round(), mod(), rem()

round()は指定に応じて、四捨五入や切り捨て・切り上げを行います。Chrome のサポートにより、ほとんどの環境で利用できるようになりました。

https://developer.mozilla.org/en-US/docs/Web/CSS/round

mod()、rem()は名前の通りです。

css
/* Math.round相当。デフォルトはnearest */
width: round(var(--width), 50px);
/* Math.ceil相当 */
width: round(up, 101px, var(--interval));
/* Math.floor相当 */
width: round(down, var(--height), var(--interval));
/* Math.tranc相当 */
margin: round(to-zero, -105px, 10px);
margin: mod(29vmin, 6vmin); /* 5vmin */
rotate: mod(135deg, -90deg); /* -45deg */
line-height: rem(21, 2); /* 1 */
rotate: rem(140deg, -90deg); /* 50deg */

#Others

折りたたみデバイス向けの Device Posture API と Viewport Segments API のオリジントライアルが開始

Origin trial for Foldable APIs | Blog | Chrome for Developers

Safari 16.4

Safari 16.4 リリース。

#Web API

多くの Web API がサポートされるようになりました。モダンブラウザの中で Safari のみがサポートしていなかったものが多く、ブラウザ互換性を見て失望することや、冗長な記述を強いられること、ポリフィルを含める必要がなくなるのは大変ありがたいです。数が多いので、使う機会があるかもしれないと思うものを適当にピックアップして軽く紹介します。

#Fullscreen API

特定の要素を全画面モードで表示したり、それを解除したりできる API です。ブラウザゲームや、賃貸情報サイトの間取り図などの拡大などで有用かもしれません。ただし、これは離脱用の UI を作らない限り、ESC キーなどで離脱する必要があるため、ユーザーのことをよく考え利用した方が良いでしょう。

js
document.addEventListener(
  "keydown",
  (e) => {
    if (e.key === "Enter") {
      toggleFullScreen();
    }
  },
  false
);

function toggleFullScreen() {
  if (!document.fullscreenElement) {
    document.documentElement.requestFullscreen();
  } else if (document.exitFullscreen) {
    document.exitFullscreen();
  }
}

#Screen Orientation API

画面の向きを取得できる API です。

js
const orientation = screen.orientation;
orientation.addEventListerner("change", () => {
  console.log(orientation.type, orientation.angle);
});

rotateBtn.addEventListener("click", async () => {
  const oppositeOrientation = screen.orientation.type.startsWith("portrait")
    ? "landscape"
    : "portrait";
  scrren.orientation
    .lock(oppositeOrientation)
    .then(() => {
      console.log(`Locked to ${oppositeOrientation}`);
    })
    .catch((error) => {
      console.error(error);
    });
});

unlockBtn.addEventListener("click", () => {
  screen.otientation.unlock();
});

#Screen Wake Lock API

端末が自動で画面を暗くしたり、ロックしたりするのを防ぐ API です。アプリケーションの継続が必要なケースや、QR コードを表示しておく必要があるアプリなどで有用です。

js
const wakeLock = await navigator.wakeLock.request("screen");
wakeLock.addEventListener("release", () => {
  console.log("Happy release wakeLock!!");
});

await heavyTask();

await wakeLock.release();

ページのタブを切り替えるなどでドキュメントの可視性が変化すると解除されてしまう点には注意が必要です。必要に応じて、visibilityChange イベントを監視し、ロックを掛け直しましょう。

js
document.addEventListener("visibilitychange", async () => {
  if (wakeLock !== null && document.visibilityState === "visible") {
    wakeLock = await navigator.wakeLock.request("screen");
  }
});

#OffscreenCanvas

OffscreenCanvas は、端的に言えば DOM と Canvas API の分離です。

従来の Canvas を利用した高度なアニメーションの描画はメインスレッドを圧迫するため、ユーザーの阻害するという問題がありました。OffscreenCanvas では、アニメーションの描画を Web Worker の Worker スレッドで行うことで、この問題が解消されます。

今までも、DOM の操作は出来ないものの重いデータ処理を Web Worker などで行うことで、負荷を軽減することは出来ましたが、OffscreenCanvas は Transferable オブジェクトであり、実質オフスクリーンでレンダリングできる DOM から分離された Canvas であるため、描画までを Web Worker で担えます。

js
const offscreenCanvas = canvas.transferControllToOffscreen();
const worker = new Worker("worker.js");
worker.postMessage({ canvas: offscreenCanvas }, [offscreenCanvas]);

// worker.js
onmessage = (event) => {
  const offscreenCanvas = event.data.canvas;
  const ctx = offscreenCanvas.getContext("webgl");
  // ...
};

#Web Push API

今までは Android などでしかサポートされていなかった Web Push が、iOS 16.4 でサポートされました。 ホーム画面に追加された Web アプリから、Push API、Notifications API、Service Worker などを駆使して、ユーザーにプッシュ通知を送ることが可能になります。

またホーム画面に追加された Web アプリでカウントを表示できる Badging API などもサポートされ、今後 PWA の利用が広がると期待されます。

https://webkit.org/blog/13878/web-push-for-web-apps-on-ios-and-ipados/

#ECMAScript features

Safari 16.4 は、非常に巨大なリリースです。JavaScritp の多くの機能も新たにサポートされました。

https://developer.apple.com/documentation/safari-release-notes/safari-16_4-release-notes

以下に、サポートされた機能のいくつかを軽く紹介します。

#Array.formAsync

Array.from が for 相当なのに対して、Array.fromAsync は for await と見れば理解しやすいと思います。 Async iterable を処理する方法として、Promise.all などがありますが、Promise.all が並列実行であるのに対して、 Array.fromAsync は for await 相当であり、順次実行されます。

https://github.com/tc39/proposal-array-from-async

#Array#group, Array#groupToMap

Array#group は、配列を指定した関数の戻り値でグルーピングしたオブジェクトを返します。 一方、Array#groupToMap は、配列を指定した関数の戻り値でグルーピングした Map を返します。

https://github.com/tc39/proposal-array-grouping

コードを見た方が理解しやすいと思います。

js
const animals = [
  { name: "たま", type: "猫" },
  { name: "みけ", type: "猫" },
  { name: "ぽち", type: "犬" },
];
console.log(animals.group((animal) => animal.type));
/* result
{
  猫: [
    { name: 'たま', type: '猫' },
    { name: 'みけ',  type: '猫' },
  ],
  犬: [
    { name: 'ぽち', type: '犬', },
  ],
}
*/
console.log(animals.groupToMap((animal) => animal.type).get("猫"));
/* result
[
  { name: 'たま', type: '猫' },
  { name: 'みけ',  type: '猫' },
]
*/

#Import Maps

ブラウザで実行される import によって読み込まれるパッケージの URL を指定する手段です。

https://github.com/WICG/import-maps#multiple-import-map-support

html
<head>
  <script type="importmap">
    {
      "imports": {
        "react": "https://unpkg.com/react@18/umd/react.development.js",
        "react-dom": "https://unpkg.com/react-dom@18/umd/react-dom.development.js"
      }
    }
  </script>
</head>
<body>
  <script type="module">
    import { createRoot } from "react-dom/client";
    import React from "react";
  </script>
</body>

著者について

Hi there. I'm hrdtbs, a frontend expert and technical consultant. I started my career in the creative industry over 13 years ago, learning on the job as a 3DCG modeler and game engineer in the indie scene.

In 2015 I began working as a freelance web designer and engineer. I handled everything from design and development to operation and advertising, delivering comprehensive solutions for various clients.

In 2016 I joined Wemotion as CTO, where I built the engineering team from the ground up and led the development of core web and mobile applications for three years.

In 2019 I joined matsuri technologies as a Frontend Expert, and in 2020 I also began serving as a technical manager supporting streamers and content creators.

I'm so grateful to be working in this field, doing something that brings me so much joy. Thanks for stopping by.